<!--
 * @description: 文件描述
 * @version: 0.0.1
 * @author: xxx
 * @Date: 2024-09-02 11:37:47
-->
<template>
  <div ref="box" id="content"></div>
</template>
<script setup>
// 引入three.js
import * as THREE from "three";
import { onMounted, ref } from "vue";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
//引入性能监视器stats.js
import Stats from "three/addons/libs/stats.module.js";
console.log(THREE, "THREE"); // 从控制台查看three.js是否导入成功；
let scene;
let mesh;
let camera;
let renderer;
let controls;
let stats = new Stats();
onMounted(() => {
  scene = new THREE.Scene();
  console.log(scene, "scenescenescene");
  //   getThreeJs();

  // 创建场景
  createScene();

  // 创建相机
  createdCamera();

  // 添加光源
  addLight();

  //  渲染器
  WebGLRenderer();

  // 轨道控制器
  updateControls();

  // 动画循环
  animate();

  window.addEventListener("resize", onWindowResize);
  //   controls.addEventListener("change", function () {
  //     renderer.render(scene, camera); //执行渲染操作
  //   }); //监听鼠标、键盘事件
});
// 创建场景
const createScene = () => {
  try {
    //创建一个长方体几何对象Geometry
    const geometry = new THREE.BoxGeometry(40, 40, 40);
    //创建一个材质对象Material
    // MeshLambertMaterial  漫反射网格材质 受光照影响
    // MeshPhongMaterial  高光 受光照影响

    const material = new THREE.MeshLambertMaterial({
      color: 0xff0000, //0xff0000设置材质颜色为红色
      transparent: true, //开启透明
      opacity: 0.5, //设置透明度
    });

     // 两个参数分别为几何体geometry、材质material
    mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh

    //设置网格模型在三维空间中的位置坐标，默认是坐标原点
    mesh.position.set(0, 0, 0);

    //把网格模型mesh添加到三维场景scene中
    scene.add(mesh);

    // for (let i = 0; i < 10; i++) {
    //    for(let j = 0; j < 10; j++){
    //     const meshMode = new THREE.Mesh(geometry, material);
    //      meshMode.position.set(i*200, j*200, 0);
    //      scene.add(meshMode);
    //    }
    // }

    // 辅助观察坐标系
    const axesHelper = new THREE.AxesHelper(150);
    scene.add(axesHelper);
  } catch (error) {
    console.log(error, "error-createScene");
  }
};

// 创建相机
const createdCamera = () => {
  try {
    //   透视投影相机PerspectiveCamera：视锥体
    // width和height用来设置Three.js输出的Canvas画布尺寸(像素px)
    const width = 800; //宽度
    const height = 500; //高度
    // 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000：远裁截面
    camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      1,
      2000
    ); // 实例化一个透视投影相机对象

    //相机在Three.js三维坐标系中的位置
    // 根据需要设置相机位置具体值
    // camera.position.set(2000, 2000, 2000);
    camera.position.set(-1000, 0, 0);
    console.log(mesh.position, "mesh.position");
    // 相机观察目标.lookAt()
   camera.lookAt(1000, 0, 1000); //指向mesh对应的位置
  } catch (error) {
    console.log(error, "error-createdCamera");
  }
};
//  渲染器
const WebGLRenderer = () => {
  try {
    // 创建渲染器对象
    renderer = new THREE.WebGLRenderer();

    // 定义threejs输出画布的尺寸(单位:像素px)
    renderer.setSize(window.innerWidth, window.innerHeight); //设置three.js渲染区域的尺寸(像素px)
    // document.body.appendChild(renderer.domElement); //指定屏幕尺寸渲染
    renderer.setClearColor(0x0000ff, 0.3);
    document.getElementById("content").appendChild(renderer.domElement); //全屏渲染
  } catch (error) {
    console.log(error, "error-WebGLRenderer");
  }
};
// 窗口大小发生改变 动态计算当前窗口大小渲染
const onWindowResize = () => {
  console.log("00000000000000");
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
};
// 添加光源
const addLight = () => {
  /* 点光源 */
  /*  //点光源：两个参数分别表示光源颜色和光照强度
  // 参数1：0xffffff是纯白光,表示光源颜色
  // 参数2：1.0,表示光照强度，可以根据需要调整
  const pointLight = new THREE.PointLight(0xffffff, 1.0);
  pointLight.intensity = 10000.0; //光照强度
  pointLight.intensity = 50000.0; //光照强度
  //   pointLight.decay = 0.0;//设置光源不随距离衰减
  //点光源位置
  pointLight.position.set(50, 50, 50); //点光源放在x轴上
  scene.add(pointLight); //点光源添加到场景中 */

  /* 环境光 */
  /*   //环境光:没有特定方向，整体改变场景的光照明暗
    const ambient = new THREE.AmbientLight(0xffffff, 0.4);
    scene.add(ambient); */

  /* 平行光 */
  const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
  // 设置光源的方向：通过光源position属性和目标指向对象的position属性计算
  directionalLight.position.set(180, 210, 80);
  // 方向光指向对象网格模型mesh，可以不设置，默认的位置是0,0,0
  directionalLight.target = mesh;
  scene.add(directionalLight);

  // DirectionalLightHelper：可视化平行光
  const dirLightHelper = new THREE.DirectionalLightHelper(
    directionalLight,
    5,
    0xff0000
  );
  scene.add(dirLightHelper);
};
// 轨道控制器
const updateControls = () => {
  controls = new OrbitControls(camera, renderer.domElement);
  controls.enableRotate = true; // 禁用旋转
  controls.maxPolarAngle = Math.PI * 0.495;
  controls.target.set(0, 0, 0);
  controls.minDistance = 20.0;
  controls.maxDistance = 300.0;
  controls.update();
};
// 材质半透明设置
const MeshConfig = () => {};
// 更新模型状态
const update = () => {
  // 更新模型的旋转
  mesh.rotation.x += 0.01;
  mesh.rotation.y += 0.01;
};
// 动画循环
const animate = () => {
  renderer.render(scene, camera);
  mesh.rotateX(0.01); //每次绕y轴旋转0.01弧度
  requestAnimationFrame(animate);
};
// const getThreeJs = () => {

//   // 创建场景
//   const scene = new THREE.Scene();

//   // 创建相机
//   const camera = new THREE.PerspectiveCamera(
//     75,
//     window.innerWidth / window.innerHeight,
//     0.1,
//     100
//   );
//   camera.position.set(10, 10, 10); // 设置相机位置
//   camera.lookAt(0, 0, 0); // 设置相机看向原点

//   // 创建渲染器
//   const renderer = new THREE.WebGLRenderer();
//   renderer.setSize(window.innerWidth, window.innerHeight);
//   console.log(box.value, "box.value");
//   document.querySelector("#content").appendChild(renderer.domElement);
//   //   const box = box.value // 获取元素
//   //   box.appendChild(renderer.domElement); // 将渲染结果添加到目标元素

//   // 添加辅助坐标
//   const axesHelper = new THREE.AxesHelper(20);
//   scene.add(axesHelper);

//   // 创建几何体
//   const geometry = new THREE.BoxGeometry(5, 5, 5);
//   const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
//   const cube = new THREE.Mesh(geometry, material);
//   scene.add(cube);

//   // 声明渲染函数
//   function animate() {
//     requestAnimationFrame(animate);
//     renderer.render(scene, camera);
//   }
//   animate();
// };
</script>
<style scoped>
#content {
  width: 800px;
  height: 800px;
}
</style>